package fr.umlv.ig.adapter;

import java.util.ArrayList;

import javax.swing.ListModel;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

import fr.umlv.ig.event.LineDataItineraryEvent;
import fr.umlv.ig.event.LineDataStationEvent;
import fr.umlv.ig.event.MetroDataLineEvent;
import fr.umlv.ig.event.StationEvent;
import fr.umlv.ig.listener.LineListener;
import fr.umlv.ig.listener.MetroListener;
import fr.umlv.ig.listener.StationListener;
import fr.umlv.ig.model.Line;
import fr.umlv.ig.model.MetroModelImpl;
import fr.umlv.ig.model.Station;

public class StationTreeModel implements TreeModel {

	private final MetroModelImpl model;
	private final DefaultMutableTreeNode root = new DefaultMutableTreeNode();
	

	private ArrayList<TreeModelListener> listeners=new ArrayList<TreeModelListener>();
	boolean firing=false;

	public StationTreeModel(MetroModelImpl model) {
		this.model = model;
		/*model.addStationListener(new StationListener() {
			
			@Override
			public void stationChange(StationEvent e) {
				
				
			}
		});*/
	}
/*
	protected void someNodesHaveChanged(int[] childIndices) {
		for (int i=0;i<childIndices.length;i++) {
			Line line =model.getLine(childIndices[i]);
			
			fireTreeNodeChanged(this,new Object[] {root,line},new int[]{1},new Object[] {line.get ()});
		}
	}

	
	protected void fireTreeNodeChanged(Object source, Object[] path, int[] childIndices, Object[] children) {
		firing=true;
		try {
			TreeModelEvent event=new TreeModelEvent(source,path,childIndices, children);
			for (TreeModelListener l:listeners) {
				l.treeNodesChanged(event);
			}
		} finally {
			firing=false;
		}
	}
*/
	
	//OK
	@Override
	public Object getRoot() {
		return root;
	}

	//OK
	@Override
	public Object getChild(Object parent, int index) {
		if(parent == root) {
			return model.getLine(index);
		}
		if(parent instanceof Line) {
			return model.getStation((Line) parent, index);
		}
		throw new AssertionError("getChild is not supported to be invoked on a leaf");
	}

	//OK
	@Override
	public int getChildCount(Object parent) {
		if(parent == root) {
			return model.getLineCount();
		}
		if(parent instanceof Line) {
			Line l = (Line) parent;
			return l.getCountStation();
		}
		throw new AssertionError("getChildCount is not supposed to be invoked on a leaf");
	}

	//OK
	@Override
	public boolean isLeaf(Object node) {
		if(node==root || node instanceof Line) {
			return false;
		}
		return true;
	}

	//OK
	@Override
	public void valueForPathChanged(TreePath path, Object newValue) {
		throw new UnsupportedOperationException();

	}

	//ok
	@Override
	public int getIndexOfChild(Object parent, Object child) {
		if(parent == root) {
			int n = model.getLineCount();
			for(int i=0; i< n ; i++) {
				Line line = model.getLine(i);
				if(line.equals(child)) {
					return i;
				}
			}
		}
		if(parent instanceof Line) {
			Line line = (Line) parent;
			int n= ((Line) parent).getCountStation();
			for(int i = 0; i< n;i++) {
				if(((Station)child).equals(model.getStation(line, i))) {
					return i;
				}
			}
		}
		throw new AssertionError("getIndexOfChild is not supposed to be invoked on a leaf");
	}

	//ok
	@Override
	public void addTreeModelListener(TreeModelListener l) {
		 listeners.add(l);

	}
	//ok
	@Override
	public void removeTreeModelListener(TreeModelListener l) {
        if (firing)
            throw new IllegalStateException("Cannot remove listeners while fire... is using them");
        listeners.remove(l);
	}


}
